home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
gdb
/
gdb_18s.zoo
/
st-traps.s
< prev
next >
Wrap
Text File
|
1992-03-25
|
7KB
|
278 lines
#
# this file contains trap handlers etc for gdb.
# see atarist.c for things that call this.
#
# Format of a context block:
# registers d0-d7 8 * 4
# registers a0-a6 7 * 4
# USP (.+60) 4
# [SSP 4]
# PC (.+64) 4
# SR (.+68) 2
# ------
# totalling 70 bytes
.data
.comm _child_context,70
.comm _dbg_context,70
.comm _old_ipl_2_vector,4
.globl _child_context
.globl _dbg_context
#
.text | this is the replacement handler
.globl _ipl_2_vector | for the IPL 2 interrupt.
_ipl_2_vector: | it's used to catch child programs
| when we spawn them
movel _old_ipl_2_vector,0x68 | restore the IPL 2 vector
movew d0,sp@- | get a temp
movew sp@(2),d0 | get the saved SR
andiw #0x0700,d0 | mask for current IPL
beq L1 | 0? ok, that means we're spawning
oriw #0x0300,sp@(2) | set ipl in saved SR to 3
movew sp@+,d0 | get reg back
rte
L1:
| we've just started a child program,
| and have ended up here, via HBLANK,
| before executing the first instruction
| of the child.
| Save the child context into the child
| context block, restore the debugger
| context from its context block, and
| RTE into it.
movew sp@+,d0 | get our d0 back
moveml d0-a6,_child_context
lea _child_context+15*4,a0
movel usp,a1 | since this runs in super mode,
movel a1,a0@+ | we get the USP this way
# movel sp,a0@+ | that's the SSP
movew sp@+,d0 | save the old SR
movel sp@+,a0@+ | get the child PC
andiw #0xF8FF,d0 | zap the IPL
oriw #0x0300,d0 | and set to IPL 3
movew d0,a0@+ | and finally save the SR
tstw 0x59e:w |_longframe
beq notlong1
addql #2,sp | "pop" the frame word
notlong1:
#
# now we have the child context safely stashed. Go run the
# debugger context
#
jmp run_debugger
#
# this thing is for faking up a return context when we're
# setting things up in the first place. This is really sort of gross.
# we funcall this routine from debugger initialization, when we're about
# ready to start the child program. We want to return to the place
# that called this routine, so we can make like we returned after
# starting the child. The way we do it is like this: Before starting
# the child, somebody will setjmp to make a jump block. We then call
# setup_fake_debugger_context with the jump block. It gets stashed here,
# and we save the SP. We then stash our registers etc in the debugger
# context block (though that's probly not strictly necessary) with the
# PC of our fake_return kludge, below. When we actually decide to switch
# context back to the debugger, we RTE to the return_kludge, which will
# fake a call to longjmp with the context block. Yow.
#
.comm fake_return_jmpbuf,4
.text
.globl _setup_fake_debugger_context
_setup_fake_debugger_context:
moveml d0-a7,_dbg_context | a7 is usp, as this runs in user mode
lea _dbg_context+15*4,a0
subl #32,a0@+ | open a hole so that when we rte,
| we'll have room
movel #return_kludge,a0@+ | the place we will want to rte to
movew #0x0300,d0 | SR: no T, no S, IPL 3
movew d0,a0@+ | and our SR.
#
# now set up the funny return jmpbuf
#
movel sp@(4),fake_return_jmpbuf
rts | and return!
#
# the thing we'll use when returning to debugger first time
# after spawning child
#
.globl _longjmp
return_kludge:
pea 1:w | push a 1, to say we jumped
movel fake_return_jmpbuf,sp@- | and the buf
jsr _longjmp | and do the jump.
#
# exception handler entry points. We assume that these all happen from
# the child program.
#
.comm _exception_number,4 | where we put what trap went off
.globl _exception_2_vector
_exception_2_vector:
movel #2,_exception_number | bus error
bra save_child
.globl _exception_3_vector
_exception_3_vector:
movel #3,_exception_number | address error
bra save_child
.globl _exception_4_vector
_exception_4_vector:
movel #4,_exception_number | Illegal instr
bra save_child
.globl _exception_5_vector
_exception_5_vector:
movel #5,_exception_number | Zero dir
bra save_child
.globl _exception_6_vector
_exception_6_vector:
movel #6,_exception_number | CHK instr
bra save_child
.globl _exception_7_vector
_exception_7_vector:
movel #7,_exception_number | TRAPV
bra save_child
.globl _exception_8_vector
_exception_8_vector:
movel #8,_exception_number | priv
bra save_child
.globl _exception_9_vector
_exception_9_vector:
movel #9,_exception_number | trace
bra save_child
.globl _trap_f_vector
_trap_f_vector:
movel #10,_exception_number | breakpoint (trap #f)
# bra save_child
#
# save the child context after some random trap
#
save_child:
moveml d0-a6,_child_context
lea _child_context+15*4,a0
movel usp,a1 | since this runs in super mode,
movel a1,a0@+ | we get the USP this way
# movel sp,a0@+ | that's the SSP
#
# if this was an address error or bus error, there's 2 extra words of
# stuff on the (system) stack.
#
tstw 0x59e:w |_longframe
beq notlong2
| new code to handle 680x0 frames, where x > 0
.data
ex_sizes: .byte 0, 0, 4, 0,0,0,0,0, 50, 12, 24, 84, 0,0,0,0
.text
movew sp@+,d0
movel sp@+,a0@+
movew d0,a0@+
moveq #0,d0 | pre-clear d0
movew sp@+,d0 | get frame word
lsrw #8,d0 | shift into place
lsrw #4,d0
lea ex_sizes,a0
moveb a0@(d0:w),d0 | d0 is now frame size
addw d0,sp | pop the whole frame off
bra long2done
| old code to handle 68000 frames incl bus err & addr err
notlong2:
movel _exception_number,d0
cmpl #2,d0
beq save_child_1
cmpl #3,d0
bne save_child_2
save_child_1:
addql #8,sp | skip the extra cruft. later, maybe stash it
| someplace? GDB apparently doesn't use this
| info
save_child_2:
movew sp@+,d0 | save the old SR
movel sp@+,a0@+ | get the child PC
movew d0,a0@+ | and finally save the SR
long2done:
#
# restore the debugger's context, and rte into it
#
run_debugger:
movel _dbg_context+15*4,a0
movel a0,usp
moveml _dbg_context,d0-a6
tstw 0x59e:w |_longframe
beq notlong3
clrw sp@-
notlong3:
movel _dbg_context+64,sp@-
movew _dbg_context+68,sp@-
rte | Poof!
#
# now for some real magic. After a trap, the way we get back into the
# child context is by having our own trap vector for trap #0. Our
# vector does a context switch!
#
.globl _trap_0_vector
_trap_0_vector:
#
# save debugger context, so we can transfer back to
# the child context
#
save_debugger:
moveml d0-a6,_dbg_context
lea _dbg_context+15*4,a0
movel usp,a1 | since this runs in super mode,
movel a1,a0@+ | we get the USP this way
# movel sp,a0@+ | that's the SSP
movew sp@+,d0 | save the old SR
movel sp@+,a0@+ | get the child PC
movew d0,a0@+ | and finally save the SR
tstw 0x59e:w |_longframe
beq notlong4
addqw #2,sp | pop frame word off
notlong4:
#
# Same deal, but run the child
#
run_child:
movel _child_context+15*4,a0
movel a0,usp
moveml _child_context,d0-a6
tstw 0x59e:w |_longframe
beq notlong5
clrw sp@-
notlong5:
movel _child_context+64,sp@-
movew _child_context+68,sp@-
rte | Poof!